package utils

import (
	"bytes"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/url"
	"strings"
	"time"
)

const (
	ContentTypeJson = "application/json;charset=utf-8"
	ContentTypeForm = "application/x-www-form-urlencoded;charset=utf-8"
)

const (
	MaxIdleCons        int = 100
	MaxIdleConsPerHost int = 100
	IdleConnTimeout    int = 2048
	ConnectTimeOut     int = 30
	KeepAlive          int = 30
)

var (
	httpClient *http.Client
)

func init() {
	httpClient = createHttpClient()
}
func createHttpClient() *http.Client {
	client := &http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			DialContext: (&net.Dialer{
				Timeout:   time.Duration(ConnectTimeOut) * time.Second, //TCP连接超时30s
				KeepAlive: time.Duration(KeepAlive) * time.Second,      //TCP keepalive保活检测定时30s
			}).DialContext,
			MaxIdleConns:          MaxIdleCons,
			MaxIdleConnsPerHost:   MaxIdleConsPerHost,
			IdleConnTimeout:       time.Duration(IdleConnTimeout) * time.Second, //闲置连接超时2048s
			ResponseHeaderTimeout: time.Second * 60,
		},
	}
	return client
}

func HttpPostJson(url string, json string) ([]byte, error) {
	return httpPost(url, map[string]string{"Content-Type": ContentTypeJson}, bytes.NewReader([]byte(json)))
}

func HttpPostForm(url string, formValues url.Values) ([]byte, error) {
	return httpPost(url, map[string]string{"Content-Type": ContentTypeForm}, strings.NewReader(formValues.Encode()))
}

func httpPost(url string, header map[string]string, body io.Reader) ([]byte, error) {
	request, err := http.NewRequest("POST", url, body)
	if err != nil {
		return nil, err
	}
	for k, v := range header {
		request.Header.Add(k, v)
	}

	response, err := httpClient.Do(request) //前面预处理一些参数，状态，Do执行发送；处理返回结果;Do:发送请求,
	if err != nil {
		return nil, err
	}
	defer response.Body.Close()
	replay, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Println("read reply error:", err)
		return nil, err
	}
	return replay, nil
}
